bitkeeper revision 1.1236.1.204 (424fc1617oxYkuT_4FpXnRPcprW5ng)
authorkaf24@viper.(none) <kaf24@viper.(none)>
Sun, 3 Apr 2005 10:11:45 +0000 (10:11 +0000)
committerkaf24@viper.(none) <kaf24@viper.(none)>
Sun, 3 Apr 2005 10:11:45 +0000 (10:11 +0000)
Xen fixes and cleanups for x86/64 guests.
Signed-off-by: Keir Fraser <keir@xensource.com>
13 files changed:
freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h
linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c
linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/system.h
linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h
netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h
xen/arch/x86/domain.c
xen/arch/x86/mm.c
xen/arch/x86/x86_64/entry.S
xen/arch/x86/x86_64/mm.c
xen/common/schedule.c
xen/include/public/arch-x86_64.h
xen/include/public/xen.h

index 95ee85f352eb6dd8c45691069de5648d728b294f..e77f5d6b9145eef4f431bd6f413c39daa2c84927 100644 (file)
@@ -176,7 +176,7 @@ static inline long HYPERVISOR_set_timer_op(uint64_t timeout)
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op),
-        "b" (timeout_hi), "c" (timeout_lo) : "memory" );
+        "b" (timeout_lo), "c" (timeout_hi) : "memory" );
 
     return ret;
 }
index 645420d502a12d811798a4c37d70fb939745bc71..1908dfa478a5aeb6f2d6e027a92840f9df30011b 100644 (file)
@@ -430,20 +430,6 @@ void xen_tlb_flush(void)
     spin_unlock_irqrestore(&update_lock, flags);
 }
 
-void xen_load_gs(unsigned long ptr)
-{
-    int cpu = smp_processor_id();
-    int idx;
-    unsigned long flags;
-    spin_lock_irqsave(&update_lock, flags);
-    idx = per_cpu(mmu_update_queue_idx, cpu);
-    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
-    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
-    per_cpu(update_queue[idx], cpu).val  = MMUEXT_LOAD_GS;
-    increment_index_and_flush();
-    spin_unlock_irqrestore(&update_lock, flags);
-}
-
 void xen_invlpg(unsigned long ptr)
 {
     int cpu = smp_processor_id();
index 0d875a79c2808cb77c0517fd4890b92798e37696..2055b32c0209253172a35f922b2194e00ccc231d 100644 (file)
@@ -218,15 +218,12 @@ static inline long
 HYPERVISOR_set_timer_op(
     u64 timeout)
 {
-    unsigned long timeout_hi = timeout >> 32;
-    unsigned long timeout_lo = timeout & 0xffffffff;    
     int ret;
 
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret)
-       : "0" ((unsigned long)__HYPERVISOR_set_timer_op), 
-          "D" (timeout_hi), "S" (timeout_lo)
+       : "0" ((unsigned long)__HYPERVISOR_set_timer_op), "D" (timeout)
        : __syscall_clobber );
 
     return ret;
index 43cae2cc0c595e284e7cee0f1c34b4c86e8a7df5..518beb6e39857ed926bd400ba096ca4d35586a40 100644 (file)
@@ -55,7 +55,7 @@
 extern void load_gs_index(unsigned);
 
 #define __load_gs_index(index) \
-        xen_load_gs((index))
+       HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, index)
 
 /*
  * Load a segment. Fall back on loading the zero
index b50c5fc3ad95a242a83941ea608f4121f2a40a8d..116e0df853972d03f0aad56242a8141e79858a81 100644 (file)
@@ -342,7 +342,7 @@ HYPERVISOR_set_timer_op(
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret), "=b" (ign1), "=c" (ign2)
-       : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
+       : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
        : "memory");
 
     return ret;
index 2ac01b4d25c67b28f206c2f6eabc28f823058374..d01af8034a486c886a33c44d4b0cae183e333a97 100644 (file)
@@ -284,7 +284,7 @@ HYPERVISOR_set_timer_op(uint64_t timeout)
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret), "=b" (ign1), "=c" (ign2)
-       : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
+       : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
        : "memory");
 
     return ret;
index 0a599661dc42191ad9c36f47cc6a330067e0ac0a..53d1ea6e3b9a7a20c916f25e8f193385414f0757 100644 (file)
@@ -573,7 +573,7 @@ void new_thread(struct exec_domain *d,
 void toggle_guest_mode(struct exec_domain *ed)
 {
     ed->arch.flags ^= TF_kernel_mode;
-    __asm__ __volatile__ ( "swapgs" );
+    __asm__ __volatile__ ( "mfence; swapgs" ); /* AMD erratum #88 */
     update_pagetables(ed);
     write_ptbase(ed);
 }
@@ -657,7 +657,7 @@ static void load_segments(struct exec_domain *p, struct exec_domain *n)
 
     /* If in kernel mode then switch the GS bases around. */
     if ( n->arch.flags & TF_kernel_mode )
-        __asm__ __volatile__ ( "swapgs" );
+        __asm__ __volatile__ ( "mfence; swapgs" ); /* AMD erratum #88 */
 
     if ( unlikely(!all_segs_okay) )
     {
@@ -711,7 +711,9 @@ static void clear_segments(void)
         "movl %0,%%ds; "
         "movl %0,%%es; "
         "movl %0,%%fs; "
-        "movl %0,%%gs; swapgs; movl %0,%%gs"
+        "movl %0,%%gs; "
+        "mfence; swapgs; " /* AMD erratum #88 */
+        "movl %0,%%gs"
         : : "r" (0) );
 }
 
index d1eb5650b8fd92f10c4f306b22df69cd7cf4b6e3..aca041e0c6e62a01f7c802d41116d9b8f3ca3997 100644 (file)
@@ -2218,8 +2218,7 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries)
 }
 
 
-long do_update_descriptor(
-    unsigned long pa, unsigned long word1, unsigned long word2)
+long do_update_descriptor(unsigned long pa, u64 desc)
 {
     unsigned long pfn = pa >> PAGE_SHIFT;
     struct desc_struct *gdt_pent, d;
@@ -2227,8 +2226,7 @@ long do_update_descriptor(
     struct exec_domain *ed;
     long ret = -EINVAL;
 
-    d.a = (u32)word1;
-    d.b = (u32)word2;
+    *(u64 *)&d = desc;
 
     LOCK_BIGLOCK(current->domain);
 
index be6572622ddb72834af7286c5e035e2f794a0226..2002acd9cebbf146a47eff3643f7295019e8c121 100644 (file)
@@ -30,6 +30,7 @@ restore_all_guest:
         popq  %r11                    # CS
         cmpw  $__GUEST_CS32,%r11
         popq  %r11                    # RFLAGS
+        cli                           # No interrupts after stack switch
         popq  %rsp                    # RSP
         je    1f
         sysretq
@@ -112,8 +113,8 @@ ENTRY(syscall_enter)
         movq  EDOMAIN_syscall_addr(%rbx),%rax
         movq  %rax,TRAPBOUNCE_eip(%rdx)
         movw  $0,TRAPBOUNCE_flags(%rdx)
-        pushq restore_all_guest(%rip)
-        jmp   create_bounce_frame
+        call  create_bounce_frame
+        jmp   restore_all_guest
 
 /* %rbx: struct exec_domain */
 hypercall:
@@ -215,7 +216,7 @@ FLT11:  movq  %rax,8(%rsi)              # ES
 FLT12:  movq  %rax,(%rsi)               # DS
 2:      subq  $16,%rsi
         movq  XREGS_r11+8(%rsp),%rax
-FLT13:  movq  %rax,(%rsi)               # R11
+FLT13:  movq  %rax,8(%rsi)              # R11
         movq  XREGS_rcx+8(%rsp),%rax
 FLT14:  movq  %rax,(%rsi)               # RCX
         /* Rewrite our stack frame and return to guest-OS mode. */
index 2d19d6f85f578a9c3cae42172464027bf95aff76..931addf30bc7c49cb63e25f74b9a3b5c37469db7 100644 (file)
@@ -249,6 +249,9 @@ long do_set_segment_base(unsigned int which, unsigned long base)
 {
     struct exec_domain *ed = current;
 
+    /* Canonicalise the base address. */
+    base &= VADDR_MASK;
+
     switch ( which )
     {
     case SEGBASE_FS:
@@ -266,6 +269,22 @@ long do_set_segment_base(unsigned int which, unsigned long base)
         wrmsr(MSR_GS_BASE, base, base>>32);
         break;
 
+    case SEGBASE_GS_USER_SEL:
+        __asm__ __volatile__ (
+            "     swapgs              \n"
+            "1:   movl %k0,%%gs       \n"
+            "     mfence; swapgs      \n" /* AMD erratum #88 */
+            ".section .fixup,\"ax\"   \n"
+            "2:   xorl %k0,%k0        \n"
+            "     jmp  1b             \n"
+            ".previous                \n"
+            ".section __ex_table,\"a\"\n"
+            "    .align 8             \n"
+            "    .quad 1b,2b          \n"
+            ".previous                  "
+            : : "r" (base&0xffff) );
+        break;
+
     default:
         return -EINVAL;
     }
@@ -284,7 +303,7 @@ int check_descriptor(struct desc_struct *d)
         goto good;
 
     /* The guest can only safely be executed in ring 3. */
-    if ( (b & _SEGMENT_DPL) != 3 )
+    if ( (b & _SEGMENT_DPL) != _SEGMENT_DPL )
         goto bad;
 
     /* All code and data segments are okay. No base/limit checking. */
index dddb96268addfd2a55d236a017ab1cdae2511d7d..fd825d2cfe8004a1b36411fee1ec626e9aa3e7a0 100644 (file)
@@ -294,20 +294,14 @@ long do_sched_op(unsigned long op)
 }
 
 /* Per-domain one-shot-timer hypercall. */
-long do_set_timer_op(unsigned long timeout_hi, unsigned long timeout_lo)
+long do_set_timer_op(s_time_t timeout)
 {
-    struct exec_domain *p = current;
+    struct exec_domain *ed = current;
 
-    rem_ac_timer(&p->timer);
+    rem_ac_timer(&ed->timer);
     
-    if ( (timeout_hi != 0) || (timeout_lo != 0) )
-    {
-        p->timer.expires = ((s_time_t)timeout_hi<<32) | ((s_time_t)timeout_lo);
-        add_ac_timer(&p->timer);
-    }
-
-    TRACE_5D(TRC_SCHED_SET_TIMER, p->domain->id, p->eid, p, timeout_hi,
-             timeout_lo);
+    if ( (ed->timer.expires = timeout) != 0 )
+        add_ac_timer(&ed->timer);
 
     return 0;
 }
index 2a6c44d4170c56dbbc62f1d54dc861886e44e958..11efe50eda41d4e7a4e8db106ca67774b1334c26 100644 (file)
@@ -92,6 +92,7 @@
 #define SEGBASE_FS          0
 #define SEGBASE_GS_USER     1
 #define SEGBASE_GS_KERNEL   2
+#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
 
 /*
  * int HYPERVISOR_switch_to_user(void)
index 43a2e87e02c2cb513e3179b839c9ac4e4f2b41aa..7dc30c9dc6ef093f68579f0e28c21364c0a842c3 100644 (file)
  * mfn: Machine frame number to be reassigned to the FD.
  *      (NB. page must currently belong to the calling domain).
  */
-#define MMUEXT_PIN_L1_TABLE      0 /* ptr = MA of frame to pin               */
-#define MMUEXT_PIN_L2_TABLE      1 /* ptr = MA of frame to pin               */
-#define MMUEXT_PIN_L3_TABLE      2 /* ptr = MA of frame to pin               */
-#define MMUEXT_PIN_L4_TABLE      3 /* ptr = MA of frame to pin               */
-#define MMUEXT_UNPIN_TABLE       4 /* ptr = MA of frame to unpin             */
-#define MMUEXT_NEW_BASEPTR       5 /* ptr = MA of new pagetable base         */
-#define MMUEXT_TLB_FLUSH_LOCAL   6 /* ptr = NULL                             */
-#define MMUEXT_INVLPG_LOCAL      7 /* ptr = VA to invalidate                 */
-#define MMUEXT_TLB_FLUSH_MULTI   8 /* ptr = NULL; mask = VCPUs to flush      */
-#define MMUEXT_INVLPG_MULTI      9 /* ptr = VA to inval.; mask = VCPUs       */
+#define MMUEXT_PIN_L1_TABLE      0
+#define MMUEXT_PIN_L2_TABLE      1
+#define MMUEXT_PIN_L3_TABLE      2
+#define MMUEXT_PIN_L4_TABLE      3
+#define MMUEXT_UNPIN_TABLE       4
+#define MMUEXT_NEW_BASEPTR       5
+#define MMUEXT_TLB_FLUSH_LOCAL   6
+#define MMUEXT_INVLPG_LOCAL      7
+#define MMUEXT_TLB_FLUSH_MULTI   8
+#define MMUEXT_INVLPG_MULTI      9
 #define MMUEXT_TLB_FLUSH_ALL    10
 #define MMUEXT_INVLPG_ALL       11
 #define MMUEXT_FLUSH_CACHE      12
-#define MMUEXT_SET_LDT          13 /* ptr = VA of table; val = # entries     */
+#define MMUEXT_SET_LDT          13
 #define MMUEXT_REASSIGN_PAGE    14
 #define MMUEXT_NEW_USER_BASEPTR 15